using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Core.Db.Dtos;
using Core.Db.Models;
using Core.Db.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using JwtRegisteredClaimNames = Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames;

namespace Core.API.Controllers;

[Route("auth")]
[ApiController]
public class AuthenticateController : ControllerBase
{
    private readonly ITouristRouteRepository _touristRouteRepository;
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly SignInManager<ApplicationUser> _signInManager;

    public AuthenticateController(ITouristRouteRepository touristRouteRepository, UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
    {
        _touristRouteRepository = touristRouteRepository;
        _userManager = userManager;
        _signInManager = signInManager;
    }

    [AllowAnonymous]
    [HttpPost("login")]
    public async Task<IActionResult> Login([FromBody] LoginDto loginDto)
    {
        //1.验证用户名密码
        var loginResult = await _signInManager.PasswordSignInAsync(loginDto.Email, loginDto.Password, false, false);
        if (loginResult.Succeeded == false)
        {
            return BadRequest();
        }

        var user = await _userManager.FindByNameAsync(loginDto.Email);

        //2.创建JWT
        var signingAlgorithm = SecurityAlgorithms.HmacSha256;
        var claims = new List<Claim>()
        {
            new Claim(JwtRegisteredClaimNames.Sub, user.Id),
            // new Claim(ClaimTypes.Role, "Admin")
        };

        var roleNames = await _userManager.GetRolesAsync(user);
        foreach (var roleName in roleNames)
        {
            var roleClaim = new Claim(ClaimTypes.Role, roleName);
            claims.Add(roleClaim);
        }

        var secretByte = "qwertyuiopasdfghjklzxcvbnm"u8.ToArray();
        var signingKey = new SymmetricSecurityKey(secretByte);
        var signingCredentials = new SigningCredentials(signingKey, signingAlgorithm);
        var token = new JwtSecurityToken(issuer: "unitysir.cn", audience: "unitysir.cn", claims, notBefore: DateTime.UtcNow, expires: DateTime.UtcNow.AddDays(1), signingCredentials);
        var tokenStr = new JwtSecurityTokenHandler().WriteToken(token);
        //3.return 200 ok + JWT
        return Ok(tokenStr);
    }

    [AllowAnonymous]
    [HttpPost("register")]
    public async Task<IActionResult> Register([FromBody] RegisterDto registerDto)
    {
        // 1. 使用用户名创建用户对象
        var user = new ApplicationUser()
        {
            UserName = registerDto.Email,
            Email = registerDto.Email,
        };

        // 2. hash 密码，保存用户
        var result = await _userManager.CreateAsync(user, registerDto.Password);
        if (result.Succeeded == false)
        {
            return BadRequest();
        }

        // 3. 初始化购物车
        var shoppingCart = new ShoppingCart()
        {
            Id = Guid.NewGuid(),
            UserId = user.Id
        };
        await _touristRouteRepository.CreateShoppingCart(shoppingCart);
        await _touristRouteRepository.SaveAsync();

        // 4. return 
        return Ok();
    }
}